home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 February: Tool Chest / Dev.CD Feb 94.toast / New System Software Extensions / QuickDraw™ GX v1.0ß2 / Interfaces & Libraries / graphics libraries / text library.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-29  |  14.1 KB  |  432 lines  |  [TEXT/MPS ]

  1. /* graphics libraries:
  2.     text library
  3.     by Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  4.     Copyright 1987 - 1991 Apple Computer, Inc.  All rights reserved.    */
  5.  
  6.  
  7.     #include <Memory.h>
  8. #ifndef bold
  9.     #include <QuickDraw.h>
  10. #endif
  11. #include "font routines.h"
  12. #include "graphics libraries.h"
  13. #include "layout routines.h"
  14.  
  15. #ifdef MacintoshIncludes
  16.     #define DrawChar gDrawChar
  17. #endif
  18.  
  19.  
  20. gxShape NewChar(char data, const gxPoint *position)
  21. {
  22.     return GXNewText(1, (unsigned char *)&data, position);
  23. }
  24.  
  25.  
  26. void SetChar(gxShape target, char data, const gxPoint *position)
  27. {
  28.     GXSetText(target, 1, (unsigned char *)&data, position);
  29. }
  30.  
  31.  
  32. void DrawChar(char data, const gxPoint *position)
  33. {
  34.     GXDrawText(1, (unsigned char *)&data, position);
  35. }
  36.  
  37.  
  38. gxShape NewCString(const char *cString, const gxPoint *position)
  39. {
  40.     register long len = 0;
  41.     register const char *find0 = cString;
  42.  
  43.     while (*find0++ != 0)
  44.         ++len;
  45.     return GXNewText(len, (unsigned char *)cString, position);
  46. }
  47.  
  48.  
  49. void SetCString(gxShape source, const char *cString, const gxPoint *position)
  50. {
  51.     register long len = 0;
  52.     register const char *find0 = cString;
  53.  
  54.     while (*find0++ != 0)
  55.         ++len;
  56.     GXSetText(source, len, (unsigned char *)cString, position);
  57. }
  58.  
  59.  
  60. fixed FixTextWidth(register const unsigned char *ch, register short len)
  61. {
  62.     gxPoint pt;
  63.     gxShape textShape = GXNewText(len, ch, nil);
  64.     fixed width = GetShapeAdvance(textShape, &pt)->x;
  65.  
  66.     GXDisposeShape(textShape);
  67.     return width;
  68. }
  69.  
  70.  
  71. fixed FixCStringWidth(register const char *ch)
  72. {
  73.     register long len = 0;
  74.     register const char *find0 = ch;
  75.  
  76.     while (*find0++ != 0)
  77.         ++len;
  78.     return FixTextWidth((unsigned char *) ch, len);
  79. }
  80.  
  81.  
  82. gxShape NewPString(register const char *pString, register const gxPoint *position)
  83. {
  84.     return GXNewText(*pString, (unsigned char *)pString + 1, position);
  85. }
  86.  
  87.  
  88. void SetPString(register gxShape source, register const char *pString, register const gxPoint *position)
  89. {
  90.     GXSetText(source, *pString, (unsigned char *) pString + 1, position);
  91. }
  92.  
  93.  
  94. fixed FixPStringWidth(register const char *ch)
  95. {
  96.     return FixTextWidth((unsigned char *) ch + 1, *ch);
  97. }
  98.  
  99.  
  100. fixed FixCharWidth(char ch)
  101. {
  102.     return FixTextWidth((unsigned char *) &ch, 1);
  103. }
  104.  
  105.  
  106. void DrawCString(register const char *ch, register const gxPoint *position)
  107. {
  108.     register long len = 0;
  109.     register const char *find0 = ch;
  110.  
  111.     while (*find0++ != 0)
  112.         ++len;
  113.     GXDrawText(len, (unsigned char *)ch, position);
  114. }
  115.  
  116.  
  117. void DrawPString(register const char *ch, register const gxPoint *position)
  118. {
  119.     GXDrawText(*ch, (unsigned char *)ch + 1, position);
  120. }
  121.  
  122.  
  123. void SetGlyphText(register gxShape source, register unsigned const char *text, long length)
  124. {
  125.     GXSetGlyphs(source, length, text, nil, nil, nil, nil, nil);
  126. }
  127.  
  128.  
  129. void SetGlyphAdvance(register gxShape source, register const long advanceBits[])
  130. {
  131.     GXSetGlyphs(source, 0, nil, nil, advanceBits, nil, nil, nil);
  132. }
  133.  
  134.  
  135. void SetGlyphStyles(register gxShape source, register const short styleRuns[], register const gxStyle glyphStyles[])
  136. {
  137.     GXSetGlyphs(source, 0, nil, nil, nil, nil, styleRuns, glyphStyles);
  138. }
  139.  
  140.  
  141. long GetGlyphText(register gxShape source, register unsigned char *text)
  142. {
  143.     return GXGetGlyphs(source, nil, text, nil, nil, nil, nil, nil, nil);
  144. }
  145.  
  146.  
  147. long GetGlyphAdvance(register gxShape source, register long advanceBits[])
  148. {
  149.     long length;
  150.  
  151.     GXGetGlyphs(source, &length, nil, nil, advanceBits, nil, nil, nil, nil);
  152.     return length;
  153. }
  154.  
  155.  
  156. long GetGlyphStyles(register gxShape source, register short styleRuns[], register gxStyle glyphStyles[])
  157. {
  158.     long runs;
  159.  
  160.     GXGetGlyphs(source, nil, nil, nil, nil, nil, &runs, styleRuns, glyphStyles);
  161.     return runs;
  162. }
  163.  
  164. #define kBoldnessFactor 18
  165.  
  166. static gxTextFace *SetCommonFace(register commonFace face)
  167. {
  168.     register gxTextFace *newFace;
  169.     register long faceLayers = 1;
  170.     register gxFaceLayer *activeLayer;
  171.     gxTransform italicTransform = nil;
  172.     gxStyle nullStyle = nil;
  173.     boolean doOutline = (face & outline) != 0;
  174.     boolean doBold = (face & bold) != 0;
  175.     boolean doShadow = (face & shadow) != 0;
  176.     boolean doShadowOutline = (face & shadow+outline) != 0;
  177.     fixed standardBolding = fixed1/kBoldnessFactor;
  178.     fixed shadowBolding = ff(3)/(kBoldnessFactor*2);
  179.     fixed shadowTranslate = 2*standardBolding / 3;
  180.     
  181.     if (face == 0)
  182.         return nil;
  183.     
  184.     {
  185.         register long shadowOutlineLayers = doShadowOutline ? 2 : 0;
  186.         register long underlineLayers = (face & underline) ? doShadowOutline + 2 : 0;
  187.  
  188.         faceLayers = shadowOutlineLayers + underlineLayers + (shadowOutlineLayers == 0);
  189.     }
  190.     if (face & italic) {
  191.         italicTransform = GXNewTransform();
  192.         
  193.         GXSkewTransform(italicTransform, -fixed1/4, 0, 0, 0);
  194.     }
  195.     if (face & underline) {
  196.         nullStyle = GXNewStyle();
  197.         GXSetStyleTextSize(nullStyle, fixed1);
  198.         GXSetStyleFont(nullStyle, 0);
  199.     }
  200.     
  201.     newFace = (gxTextFace *) NewPtr(sizeof(gxTextFace) +  (faceLayers - gxAnyNumber) * sizeof(gxFaceLayer));
  202.     newFace->faceLayers = faceLayers;
  203.     ResetMapping(&newFace->advanceMapping);
  204.     if ( ((face & extend) != 0) ^ ((face & condense) != 0) )
  205.         if (face & extend)
  206.             ScaleMapping(&newFace->advanceMapping, ff(100)/85, fixed1, 0, 0);
  207.         else
  208.             ScaleMapping(&newFace->advanceMapping, ff(85)/100, fixed1, 0, 0);
  209.     
  210.     activeLayer = &newFace->faceLayer[0];
  211.     
  212.     if (doShadowOutline) {
  213.         if (face & underline) {
  214.             /*** doesn't discriminate between outline and shadow ***/
  215.             activeLayer->outlineFill = gxNoFill;
  216.             activeLayer->flags = gxUnderlineAdvanceLayer;
  217.             activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
  218.             activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
  219.             GXMoveTransform(activeLayer->outlineTransform, 0, ff(2)/kBoldnessFactor);
  220.             activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
  221.             ++activeLayer;
  222.             
  223.             activeLayer->outlineFill = gxNoFill;
  224.             activeLayer->flags = gxUnderlineAdvanceLayer;
  225.             activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
  226.             GXSetStylePen(activeLayer->outlineStyle, fixed1/8);
  227.             activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
  228.             GXMoveTransform(activeLayer->outlineTransform, 0, ff(2+doShadow)/kBoldnessFactor);
  229.             activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
  230.             ++activeLayer;
  231.  
  232.             activeLayer->outlineFill = gxNoFill;
  233.             activeLayer->flags = gxUnderlineAdvanceLayer + gxWhiteLayer;
  234.             activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
  235.             GXSetStylePen(activeLayer->outlineStyle, fixed1/16);
  236.             activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
  237.             GXMoveTransform(activeLayer->outlineTransform, 0, ff(2+doShadow)/kBoldnessFactor);
  238.             activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
  239.             ++activeLayer;
  240.         }
  241.         
  242.         activeLayer->outlineFill = gxWindingFill;
  243.         activeLayer->flags = 0;
  244.         activeLayer->outlineStyle = nil;
  245.         activeLayer->boldOutset.x = (doShadow ? shadowBolding : standardBolding) + standardBolding*doBold;
  246.         activeLayer->boldOutset.y = doShadow ? shadowBolding : standardBolding;
  247.         if (doShadow) {
  248.             activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
  249.             GXMoveTransform(activeLayer->outlineTransform, shadowTranslate, shadowTranslate);
  250.         } else
  251.             activeLayer->outlineTransform = italicTransform ? GXCloneTransform(italicTransform) : nil;
  252.         ++activeLayer;
  253.         
  254.         activeLayer->outlineFill = gxWindingFill;
  255.         activeLayer->flags = gxWhiteLayer;
  256.         activeLayer->outlineStyle = nil;
  257.         activeLayer->outlineTransform = italicTransform ? GXCloneTransform(italicTransform) : nil;
  258.         activeLayer->boldOutset.x = doBold*standardBolding;
  259.         activeLayer->boldOutset.y = 0;  
  260.     } else {
  261.         if (face & underline) {
  262.             activeLayer->outlineFill = gxNoFill;
  263.             activeLayer->flags = gxUnderlineAdvanceLayer;
  264.             activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
  265.             activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
  266.             GXMoveTransform(activeLayer->outlineTransform, 0, ff(doBold+1)/kBoldnessFactor + shadowTranslate);
  267.             activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
  268.             ++activeLayer;
  269.             
  270.             activeLayer->outlineFill = gxNoFill;
  271.             activeLayer->flags = gxUnderlineAdvanceLayer;
  272.             activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
  273.             GXSetStylePen(activeLayer->outlineStyle, fixed1/12);    
  274.             activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
  275.             GXMoveTransform(activeLayer->outlineTransform, 0, ff(doBold+1)/kBoldnessFactor + shadowTranslate);
  276.             activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
  277.             ++activeLayer;
  278.         } 
  279.     
  280.         activeLayer->outlineFill = gxWindingFill;
  281.         activeLayer->flags = 0;
  282.         activeLayer->outlineStyle = nil;
  283.         activeLayer->outlineTransform = italicTransform ? GXCloneTransform(italicTransform) : nil;
  284.         activeLayer->boldOutset.x = doBold * standardBolding;
  285.         activeLayer->boldOutset.y = doBold * standardBolding;
  286.     }
  287.     if (activeLayer != &newFace->faceLayer[faceLayers-1])
  288.         DebugStr("\pMiscalculated size of gxTextFace structure");
  289.     
  290.     if (italicTransform)
  291.         GXDisposeTransform(italicTransform);
  292.     if (nullStyle)
  293.         GXDisposeStyle(nullStyle);
  294.         
  295.     return newFace;
  296. }
  297.  
  298.  
  299. static void DisposeFaceParts(gxTextFace *newFace)
  300. {
  301.     long activeLayer = newFace->faceLayers - 1;
  302.  
  303.     do {
  304.         if (newFace->faceLayer[activeLayer].outlineStyle)
  305.             GXDisposeStyle(newFace->faceLayer[activeLayer].outlineStyle);
  306.         if (newFace->faceLayer[activeLayer].outlineTransform)
  307.             GXDisposeTransform(newFace->faceLayer[activeLayer].outlineTransform);
  308.     } while (--activeLayer >= 0);
  309.     DisposPtr((Ptr) newFace);
  310. }
  311.  
  312.  
  313. void SetStyleCommonFace(gxStyle source, commonFace face)
  314. {
  315.     gxTextFace *newFace = SetCommonFace(face);
  316.  
  317.     GXSetStyleFace(source, newFace);
  318.     if (newFace)
  319.         DisposeFaceParts(newFace);
  320. }
  321.  
  322.  
  323. void SetShapeCommonFace(gxShape source, commonFace face)
  324. {
  325.     gxTextFace *newFace = SetCommonFace(face);
  326.  
  327.     GXSetShapeFace(source, newFace);
  328.     if (newFace)
  329.         DisposeFaceParts(newFace);
  330. }
  331.  
  332.  
  333. commonFace GetStyleCommonFace(gxStyle source)
  334. {
  335.     long layers = GXGetStyleFace(source, nil);
  336.  
  337.     if (layers == -1)
  338.         return 0;
  339.     {   gxTextFace *realFacePtr = (gxTextFace *) NewPtr(sizeof(gxTextFace) +  (layers - 1) * sizeof(gxFaceLayer));
  340.         commonFace face = 0;
  341.         long activeLayer = 0;
  342.         gxStyle curStyle;
  343.         gxTransform curTransform;
  344.  
  345.         GXGetStyleFace(source, realFacePtr);
  346.         if (realFacePtr->faceLayers == 2) {
  347.             face |= shadow;
  348.             activeLayer++;
  349.         }
  350.         if (realFacePtr->faceLayer[activeLayer].outlineFill == gxClosedFrameFill)
  351.             face |= outline;
  352.         if (realFacePtr->faceLayer[activeLayer].flags & gxUnderlineAdvanceLayer)
  353.             face |= underline;
  354.         if (curStyle = realFacePtr->faceLayer[activeLayer].outlineStyle)
  355.         if (realFacePtr->faceLayer[activeLayer].boldOutset.x | realFacePtr->faceLayer[activeLayer].boldOutset.y)
  356.             face |= bold;
  357.         if (curTransform = realFacePtr->faceLayer[activeLayer].outlineTransform)
  358.         {   gxMapping map;
  359.  
  360.             GXGetTransformMapping(curTransform, &map);
  361.             if (map.map[0][0] >= IntToFixed(100) / 85)
  362.                 face |= extend;
  363.             if (map.map[0][0] <= IntToFixed(85) / 100)
  364.                 face |= condense;
  365.             if (map.map[1][0])
  366.                 face |= italic;
  367.         }
  368.         {   gxFaceLayer *layer = realFacePtr->faceLayer;
  369.  
  370.             while (layers--) {
  371.                 DisposeStyleAt(&layer->outlineStyle);
  372.                 DisposeTransformAt(&layer->outlineTransform);
  373.                 layer++;
  374.             }
  375.         }
  376.         return face;
  377.     }
  378. }
  379.  
  380.  
  381. commonFace GetShapeCommonFace(gxShape source)
  382. {
  383.     return GetStyleCommonFace(GXGetShapeStyle(source));
  384. }
  385.  
  386. #define offsetField(type, field)        ((long) &((type *) 0)->field)
  387.  
  388. gxPoint *GetShapeAdvance(gxShape source, gxPoint *advancePt)
  389. {
  390.     gxShapeType type = GXGetShapeType(source);
  391.  
  392.     switch (type) {
  393.         case gxEmptyType:
  394.         case gxFullType:
  395.             GXPostGraphicsWarning(graphic_type_does_not_contain_points);
  396.         break;
  397.         case gxPointType:
  398.         case gxLineType:
  399.         case gxCurveType:
  400.         case gxRectangleType:
  401.         case gxPolygonType:
  402.         case gxPathType:
  403.         case gxPictureType:
  404.             {   gxRectangle bounds;
  405.  
  406.                 GXGetShapeBounds(source, 0, &bounds);
  407.                 advancePt->x = bounds.right - bounds.left;
  408.                 advancePt->y = bounds.bottom - bounds.top;
  409.             }
  410.         break;
  411.         case gxTextType:
  412.         case gxGlyphType:
  413.         case gxLayoutType:
  414.             {   long characters;
  415.                 gxPoint *positions;
  416.  
  417.                 if (type == gxTextType)
  418.                     GXGetText(source, &characters, nil, nil);
  419.                 else if (type == gxGlyphType)
  420.                     GXGetGlyphs(source, &characters, nil, nil, nil, nil, nil, nil, nil);
  421.                 else characters = GXGetLayoutGlyphs(source, nil, nil, nil, nil, nil, nil, nil);
  422.                 positions = (void *) NewPtr((characters + 1) * sizeof(gxPoint));
  423.                 GXGetGlyphMetrics(source, positions, nil, nil);
  424.                 advancePt->x = positions[characters].x - positions[0].x;
  425.                 advancePt->y = positions[characters].y - positions[0].y;
  426.                 DisposPtr((void *) positions);
  427.             }
  428.         break;
  429.     }
  430.     return advancePt;
  431. }
  432.